#include "common.h"
#include "lptmr.h"

extern int re_init_clk;
extern int clock_freq_hz;

int lptmr_status=0x00;

void time_delay_ms(unsigned int count_val){

    /* Check LPTMR status */
    if(lptmr_status!=0x00){
        printf("Error: LPTMR module is in use\n");
        while(1);
    }

    /* Update LPTMR status */
    lptmr_status=0x03;

    /* Make sure the clock to the LPTMR is enabled */
    SIM_SCGC5|=SIM_SCGC5_LPTMR_MASK;

    /* Reset LPTMR settings */
    LPTMR0_CSR=0;

    /* Set the compare value to the number of ms to delay */
    LPTMR0_CMR=count_val;

    /* Set up LPTMR to use 1kHz LPO with no prescaler as its clock source */
    LPTMR0_PSR=LPTMR_PSR_PCS(1)|LPTMR_PSR_PBYP_MASK;

    /* Start the timer */
    LPTMR0_CSR|=LPTMR_CSR_TEN_MASK;

    /* Wait for counter to reach compare value */
    while(!(LPTMR0_CSR&LPTMR_CSR_TCF_MASK));

    /* Disable counter and Clear Timer Compare Flag */
    LPTMR0_CSR&=~LPTMR_CSR_TEN_MASK;

    lptmr_status=0x00;
}

void lptmr_isr(void){
    printf("\n****LPT ISR entered*****\r\n");

    // enable timer
    // enable interrupts
    // clear the flag
    LPTMR0_CSR|=LPTMR_CSR_TCF_MASK;   // write 1 to TCF to clear the LPT timer compare flag
    LPTMR0_CSR=(LPTMR_CSR_TEN_MASK|LPTMR_CSR_TIE_MASK|LPTMR_CSR_TCF_MASK);

}

int lptmr_init(int pin, int clock_source){
    if(pin<0||pin>2
      ||clock_source<0||clock_source>3)
        return -1;

    SIM_SCGC5|=SIM_SCGC5_LPTMR_MASK;

    LPTMR0_PSR=(LPTMR_PSR_PRESCALE(2) // 0000 is div 2
               |!LPTMR_PSR_PBYP_MASK  // LPO pssses filter
               |LPTMR_PSR_PCS(clock_source)) ; // use the choice of clock
    /*
    if (clock_source== 0)
      printf("\n LPTMR Clock source is the MCGIRCLK \n\r");
    if (clock_source== 1)
      printf("\n LPTMR Clock source is the LPOCLK \n\r");
    if (clock_source== 2)
      printf("\n LPTMR Clock source is the ERCLK32 \n\r");
    if (clock_source== 3)
      printf("\n LPTMR Clock source is the OSCERCLK \n\r");
    */
             
    LPTMR0_CMR=LPTMR_CMR_COMPARE_MASK;  //Set compare value as maximum

    LPTMR0_CSR=(!LPTMR_CSR_TIE_MASK   // LPT interrupt disabled
               | LPTMR_CSR_TPS(pin)     //TMR pin select
               |!LPTMR_CSR_TPP_MASK   //TMR Pin polarity
               |!LPTMR_CSR_TFC_MASK   // Timer Free running counter is reset whenever TCF is set
               |LPTMR_CSR_TMS_MASK   //LPTMR0 as Pulse counter
               );
    LPTMR0_CSR|=(LPTMR_CSR_TEN_MASK   //Turn on LPT and start counting
               |LPTMR_CSR_TCF_MASK     // Clear any pending interrupt
               );

    lptmr_status=0x02; // Update LPTMR status

    return 0;
}

uint16 lptmr_read(void){
    uint16 cnt;

    /* Update CNR register value */
    LPTMR0_CNR=0xFF;

    /* Read counter value */
    cnt=LPTMR0_CNR;

    /* Reset CNR value */
    LPTMR0_CSR&=~LPTMR_CSR_TEN_MASK;
    LPTMR0_CSR|=LPTMR_CSR_TEN_MASK;

    return cnt;
}
